#napomena: zbog toga sto se u Pythonu ne moze kreirati referenca (pokazivac)
#na varijablu, sve varijable moraju biti elementi liste. Reference su potrebne
#za prenosenje izvedenih svojstava po stablu
# Pomocne funkcije (one koje nisu akcije semantickog analizatora) navedene su
# iza akcija analizatora i imaju ime oblika _ime_funkcije

from SintaksnoStablo import *
import sys

poceo = 0
x = 0
#PRAVILA ZA IZRAZE
# dopuna: za nasljedna svojstva ide prvo dodjela, onda provjera
#         za izvedena svojstva ide prvo provjera, onda dodjela

def primarni_izraz (cvor):
        global gen
        global dekl

        if cvor.djeca[0].ime == 'IDN':

                #dodjela
                tmp = _vrati_tip_l_izraz (cvor, cvor.djeca[0].ljedinka)
                if tmp == 0:
                        _greska(cvor)

                cvor.tip = tmp[0]
                cvor.l_izraz = tmp[1]                

        elif cvor.djeca[0].ime == 'BROJ':

                #dodjela
                cvor.tip.append('int')
                cvor.l_izraz.append(0)

                #uvjeti
                if not _unutar_raspona(cvor.djeca[0].ljedinka):
                        _greska(cvor)

                if (gen.rfind('F_MAIN') == 28):
                    poceo = 0
                else:
                    poceo = 1
                if (poceo == 0):
                    dekl = "G_X   DW %D " + cvor.djeca[0].ljedinka + "\n"
                else:
                    gen += "LOAD R6, (G_X)\n"
                    dekl = "G_X   DW %D " + cvor.djeca[0].ljedinka + "\n"
#                    gen += "MOVE " + cvor.djeca[0].ljedinka + ", R6\n"

        elif cvor.djeca[0].ime == 'ZNAK':

                #dodjela
                cvor.tip.append('char')
                cvor.l_izraz.append(0)

                #uvjeti
                if not _ispravan_znak(cvor.djeca[0].ljedinka):
                        _greska(cvor)

                if (gen.rfind('F_MAIN') == 28):
                    poceo = 0
                else:
                    poceo = 1
                if (poceo == 0):
                    dekl = "G_X   DW %D " + cvor.djeca[0].ljedinka + "\n"
                else:
                    gen += "LOAD R6, (G_X)\n"
                    dekl = "G_X   DW %D " + cvor.djeca[0].ljedinka + "\n"
#                    gen += "MOVE " + cvor.djeca[0].ljedinka + ", R6\n"

        elif cvor.djeca[0].ime == 'NIZ_ZNAKOVA':
                #dodjela
                cvor.tip.append('char')
                cvor.niz.append(1)
                cvor.const.append(1)
                cvor.l_izraz.append(0)

                #uvjeti
                for n in cvor.djeca[0].ljedinka:
                        if not _ispravan_znak(n):
                                _greska(cvor)

        elif (cvor.djeca[0].ime == 'L_ZAGRADA' and
                  cvor.djeca[1].ime == '<izraz>' and
                  cvor.djeca[2].ime == 'R_ZAGRADA'):

                #dodjela
                cvor.tip = cvor.djeca[1].tip
                cvor.l_izraz = cvor.djeca[1].l_izraz

                #uvjeti
                izraz(cvor.djeca[1])

        else:
                _greska(cvor)

def postfiks_izraz(cvor):

        if cvor.djeca[0].ime == '<primarni_izraz>':

                #uvjeti
                primarni_izraz(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.l_izraz = cvor.djeca[0].l_izraz

        elif (cvor.djeca[0].ime == '<postfiks_izraz>' and
                  cvor.djeca[1].ime == 'L_UGL_ZAGRADA' and
                  cvor.djeca[2].ime == '<izraz>' and
                  cvor.djeca[3].ime == 'D_UGL_ZAGRADA'):

                # uvjeti
                postfiks_izraz(cvor.djeca[0])
                if len(cvor.djeca[0].niz) > 0: #postfiks_izraz.tip = niz(X)
                        _greska(cvor)
                izraz(cvor.djeca[2])
                if not (_provjeri_tildu(cvor.djeca[2].tip[0], 'int')):
                        _greska(cvor)

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                if len(cvor.djeca[0].const) > 0:
                        cvor.l_izraz = 0
                else:
                        cvor.l_izraz = 1

        elif (cvor.djeca[0].ime == '<postfiks_izraz>' and
                  cvor.djeca[1].ime == 'L_ZAGRADA' and
                  cvor.djeca[2].ime == 'D_ZAGRADA'):

                #uvjeti
                postfiks_izraz(cvor.djeca[0])
                if (not (cvor.djeca[0].param == ['void'] and
                         cvor.djeca[0].tip[0] == 'funkcija')):
                        _greska(cvor)

                #dodjela
                cvor.tip = cvor.djeca[0].pov
                cvor.l_izraz.append(0)

        elif (cvor.djeca[0].ime == '<postfiks_izraz>' and
                  cvor.djeca[1].ime == 'L_ZAGRADA' and
                  cvor.djeca[2].ime == '<lista_argumenata>' and
                  cvor.djeca[3].ime == 'D_ZAGRADA'):

                #uvjeti
                postfiks_izraz(cvor.djeca[0])
                lista_argumenata(cvor.djeca[2])
                if not (cvor.djeca[0].tip[0] == 'funkcija' and
                        cvor.djeca[0].param == cvor.djeca[2].tip and
                        cvor.djeca[0].pov == pov):
                        _greska(cvor)
                for n in range(0, len(cvor.djeca[0].param)):
                        if not _provjeri_tildu(lista_argumenata.tipovi[n],
                                               cvor.djeca[0].param[n]):
                                _greska(cvor)
                #dodjela
                cvor.tip = cvor.djeca[0].pov
                cvor.l_izraz.append(0)

        elif (cvor.djeca[0].ime == '<postfiks_izraz>' and
                  (cvor.djeca[1].ime == 'OP_INC' or
                   cvor.djeca[1].ime == 'OP_DEC')):

                #uvjeti
                postfiks_izraz(cvor.djeca[0])
                if not (cvor.djeca[0].l_izraz[0] == 1 and
                        _provjeri_tildu(cvor.djeca[0].tip[0], 'int')):
                        _greska(cvor)

                #dodjela
                cvor.tip.append('int')
                cvor.l_izraz.append(0)

        else:
                _greska(cvor)

def lista_argumenata(cvor):

        if cvor.djeca[0].ime == '<izraz_pridruzivanja>':

                #uvjeti
                izraz_pridruzivanja(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip

        elif (cvor.djeca[0].ime == '<lista_argumenata>' and
                  cvor.djeca[1].ime == 'ZAREZ' and
                  cvor.djeca[2].ime == '<izraz_pridruzivanja>'):

                #tipovi <-  <lista_argumenata>.tipovi + [ <izraz_pridruzivanja>.tip ]
                lista_argumenata(cvor.djeca[0])		#provjeri(<lista_argumenata>)
                izraz_pridruzivanja(cvor.djeca[2])	#provjeri(<izraz_pridruzivanja>)
                cvor.tip.extend(cvor.djeca[0].tip)
                cvor.tip.extend(cvor.djeca[2].tip)

        else:
                _greska(cvor)

def unarni_izraz(cvor):

        if cvor.djeca[0].ime == '<postfiks_izraz>':

                #uvjeti
                postfiks_izraz(cvor.djeca[0])
                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.l_izraz = cvor.djeca[0].l_izraz

        elif ((cvor.djeca[0].ime == 'OP_INC' or
               cvor.djeca[0].ime == 'OP_DEC') and
              cvor.djeca[1].ime == '<unarni_izraz>'):

                #uvjeti
                unarni_izraz(cvor.djeca[1])
                if not (cvor.djeca[1].l_izraz == 1 and
                        _provjeri_tildu(cvor.djeca[1].tip[0], 'int')):
                        _greska(cvor)
                #dodjela
                cvor.tip.append('int')
                cvor.l_izraz.append(0)

        elif (cvor.djeca[0].ime == '<unarni_operator>' and
              cvor.djeca[1].ime == '<cast_izraz>'):

                #uvjeti
                cast_izraz(cvor.djeca[1])
                if (not _provjeri_tildu(cvor.djeca[1].tip[0], 'int')):
                        _greska(cvor)

                #dodjela
                cvor.tip.append('int')
                cvor.l_izraz.append(0)

        else:
                _greska(cvor)

def unarni_operator(cvor):
                if (cvor.djeca[0].ime not in
                    ['PLUS', 'MINUS', 'OP_TILDA', 'OP_NEG']):
                        _greska(cvor)

def cast_izraz(cvor):

        if cvor.djeca[0].ime == '<unarni_izraz>':

                #uvjeti
                unarni_izraz(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.l_izraz = cvor.djeca[0].l_izraz

        elif (cvor.djeca[0].ime == 'L_ZAGRADA' and
              cvor.djeca[1].ime == '<ime_tipa>' and
              cvor.djeca[2].ime == 'D_ZAGRADA' and
              cvor.djeca[3].ime == '<cast_izraz>'):

                #uvjeti
                ime_tipa(cvor.djeca[1])
                cast_izraz(cvor.djeca[3])
                #ime_tipa.tip mora biti [const](int || char)
                if not (cvor.djeca[1].ime == 'char' or
                        cvor.djeca[1].ime == 'int' or
                        cvor.djeca[1].ime == 'T' or
                        cvor.djeca[1].ime == 'X'):
                        _greska(cvor)

                #dodjela
                cvor.tip = cvor.djeca[1].tip
                cvor.l_izraz.append(0)

        else:
                _greska(cvor)

def ime_tipa(cvor):

        if cvor.djeca[0].ime == '<specifikator_tipa>':

                #uvjeti
                specifikator_tipa(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip

        elif (cvor.djeca[0].ime == 'KR_CONST' and
              cvor.djeca[1].ime == '<specifikator_tipa>'):

                #uvjeti
                specifikator_tipa(cvor.djeca[1])
                if cvor.djeca[1].tip[0] == 'void':
                        _greska(cvor)

                #dodjela
                cvor.const.append(1)
                cvor.tip = cvor.djeca[1].tip

        else:
                _greska(cvor)

def specifikator_tipa(cvor):

        if cvor.djeca[0].ime == 'KR_VOID':
                cvor.tip.append('void')

        elif cvor.djeca[0].ime == 'KR_CHAR':
                cvor.tip.append('char')

        elif cvor.djeca[0].ime == 'KR_INT':
                cvor.tip.append('int')

        else:
                _greska(cvor)

def multiplikativni_izraz(cvor):

        if cvor.djeca[0].ime == '<cast_izraz>':

                #uvjeti
                cast_izraz(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.l_izraz = cvor.djeca[0].l_izraz

        elif (cvor.djeca[0].ime == '<multiplikativni_izraz>' and
              (cvor.djeca[1].ime == 'OP_PUTA' or
               cvor.djeca[1].ime == 'OP_DIJELI' or
               cvor.djeca[1].ime == 'OP_MOD') and
              cvor.djeca[2].ime == '<cast_izraz>'):

                #uvjeti
                multiplikativni_izraz(cvor.djeca[0])
                if not _provjeri_tildu(cvor.djeca[0].tip[0], 'int'):
                        _greska(cvor)
                cast_izraz(cvor.djeca[2])
                if not _provjeri_tildu(cvor.djeca[2].tip[0], 'int'):
                        _greska(cvor)

                #dodjela
                cvor.tip.append('int')
                cvor.l_izraz.append(0)

        else:
                _greska(cvor)

def aditivni_izraz(cvor):

        if cvor.djeca[0].ime == '<multiplikativni_izraz>':

                #uvjeti
                multiplikativni_izraz(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.l_izraz = cvor.djeca[0].l_izraz

        elif (cvor.djeca[0].ime == '<aditivni_izraz>' and
              (cvor.djeca[1].ime == 'PLUS' or cvor.djeca[1].ime == 'MINUS') and
              cvor.djeca[2].ime == '<multiplikativni_izraz>' ):

                #uvjeti
                aditivni_izraz(cvor.djeca[0])
                if not _provjeri_tildu(cvor.djeca[0].tip[0], 'int'):
                        _greska(cvor)
                multiplikativni_izraz(cvor.djeca[2])
                if not _provjeri_tildu(cvor.djeca[2].tip[0], 'int'):
                        _greska(cvor)

                #dodjela
                cvor.tip.append('int')
                cvor.l_izraz.append(0)

        else:
                _greska(cvor)

def odnosni_izraz(cvor):

        if cvor.djeca[0].ime == '<aditivni_izraz>':

                #uvjeti
                aditivni_izraz(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.l_izraz = cvor.djeca[0].l_izraz

        elif (cvor.djeca[0].ime == '<odnosni_izraz>' and
              (cvor.djeca[1].ime == 'OP_LT' or
               cvor.djeca[1].ime == 'OP_GT' or
               cvor.djeca[1].ime == 'OP_LTE' or
               cvor.djeca[1].ime == 'OP_GTE') and
              cvor.djeca[2].ime == '<aditivni_izraz>'):

                #uvjeti
                odnosni_izraz(cvor.djeca[0])
                if not _provjeri_tildu(cvor.djeca[0].tip[0], 'int'):
                        _greska(cvor)
                aditivni_izraz(cvor.djeca[2])
                if not _provjeri_tildu(cvor.djeca[2].tip[0], 'int'):
                        _greska(cvor)

                #dodjela
                cvor.tip.append('int')
                cvor.l_izraz.append(0)

        else:
                _greska(cvor)

def jednakosni_izraz(cvor):

        if cvor.djeca[0].ime == '<odnosni_izraz>':

                #uvjeti
                odnosni_izraz(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.l_izraz = cvor.djeca[0].l_izraz

        elif (cvor.djeca[0].ime == '<jednakosni_izraz>' and
              (cvor.djeca[1].ime == 'OP_EQ' or
               cvor.djeca[1].ime == 'OP_NEQ') and
              cvor.djeca[2].ime == '<odnosni_izraz>'):

                #uvjeti
                jednakosni_izraz(cvor.djeca[0])
                if not _provjeri_tildu(cvor.djeca[0].tip[0], 'int'):
                        _greska(cvor)
                odnosni_izraz(cvor.djeca[0])
                if not _provjeri_tildu(cvor.djeca[2].tip[0], 'int'):
                        _greska(cvor)

                #dodjela
                cvor.tip.append('int')
                cvor.l_izraz.append(0)

        else:
                _greska(cvor)

def bin_i_izraz(cvor):

        if cvor.djeca[0].ime == '<jednakosni_izraz>':

                #uvjeti
                jednakosni_izraz(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.l_izraz = cvor.djeca[0].l_izraz

        elif (cvor.djeca[0].ime == '<bin_i_izraz>' and
              cvor.djeca[1].ime == 'OP_BIN_I' and
              cvor.djeca[2].ime == '<jednakosni_izraz>'):

                #uvjeti
                bin_i_izraz(cvor.djeca[0])
                if not _provjeri_tildu(cvor.djeca[0].tip[0], 'int'):
                        _greska(cvor)
                jednakosni_izraz(cvor.djeca[2])
                if not _provjeri_tildu(cvor.djeca[2].tip[0], 'int'):
                        _greska(cvor)

                #dodjela
                cvor.tip.append('int')
                cvor.l_izraz.append(0)

        else:
                _greska(cvor)

def bin_xili_izraz(cvor):

        if cvor.djeca[0].ime == '<bin_i_izraz>':

                #uvjeti
                bin_i_izraz(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.l_izraz = cvor.djeca[0].l_izraz

        elif (cvor.djeca[0].ime == '<bin_xili_izraz>' and
              cvor.djeca[1].ime == 'OP_BIN_XILI' and
              cvor.djeca[2].ime == '<bin_i_izraz>'):

                #uvjeti
                bin_xili_izraz(cvor.djeca[0])
                if not _provjeri_tildu(cvor.djeca[0].tip[0], 'int'):
                        _greska(cvor)
                bin_i_izraz(cvor.djeca[2])
                if not _provjeri_tildu(cvor.djeca[2].tip[0], 'int'):
                        _greska(cvor)

                #dodjela
                cvor.tip.append('int')
                cvor.l_izraz.append(0)

        else:
                _greska(cvor)

def bin_ili_izraz(cvor):

        if cvor.djeca[0].ime == '<bin_xili_izraz>':

                #uvjeti
                bin_xili_izraz(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.l_izraz = cvor.djeca[0].l_izraz

        elif (cvor.djeca[0].ime == '<bin_ili_izraz>' and
              cvor.djeca[1].ime == 'OP_BIN_ILI' and
              cvor.djeca[2].ime == '<bin_xili_izraz>'):

                #uvjeti
                bin_ili_izraz(cvor.djeca[0])
                if not _provjeri_tildu(cvor.djeca[0].tip[0], 'int'):
                        _greska(cvor)
                bin_xili_izraz(cvor.djeca[2])
                if not _provjeri_tildu(cvor.djeca[2].tip[0], 'int'):
                        _greska(cvor)

                #dodjela
                cvor.tip.append('int')
                cvor.l_izraz.append(0)

        else:
                _greska(cvor)

def log_i_izraz(cvor):

        if cvor.djeca[0].ime == '<bin_ili_izraz>':

                #uvjeti
                bin_ili_izraz(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.l_izraz = cvor.djeca[0].l_izraz

        elif (cvor.djeca[0].ime == '<log_i_izraz>' and
              cvor.djeca[1].ime == 'OP_I' and
              cvor.djeca[2].ime == '<bin_ili_izraz>'):

                #uvjeti
                log_i_izraz(cvor.djeca[0])
                if not _provjeri_tildu(cvor.djeca[0].tip[0], 'int'):
                        _greska(cvor)
                bin_ili_izraz(cvor.djeca[2])
                if not _provjeri_tildu(cvor.djeca[2].tip[0], 'int'):
                        _greska(cvor)

                #dodjela
                cvor.tip.append('int')
                cvor.l_izraz.append(0)

        else:
                _greska(cvor)

def log_ili_izraz(cvor):

        if cvor.djeca[0].ime == '<log_i_izraz>':

                #uvjeti
                log_i_izraz(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.l_izraz = cvor.djeca[0].l_izraz

        elif (cvor.djeca[0].ime == '<log_ili_izraz>' and
              cvor.djeca[1].ime == 'OP_ILI' and
              cvor.djeca[2].ime == '<log_i_izraz>'):

                #uvjeti
                log_ili_izraz(cvor.djeca[0])
                if not _provjeri_tildu(cvor.djeca[0].tip[0], 'int'):
                        _greska(cvor)
                log_i_izraz(cvor.djeca[2])
                if not _provjeri_tildu(cvor.djeca[2].tip[0], 'int'):
                        _greska(cvor)

                #dodjela
                cvor.tip.append('int')
                cvor.l_izraz.append(0)

        else:
                _greska(cvor)

def izraz_pridruzivanja(cvor):

        if cvor.djeca[0].ime == '<log_ili_izraz>':

                #uvjeti
                log_ili_izraz(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.l_izraz = cvor.djeca[0].l_izraz

        elif (cvor.djeca[0].ime == '<postfiks_izraz>' and
              cvor.djeca[1].ime == 'OP_PRIDRUZI' and
              cvor.djeca[2].ime == '<izraz_pridruzivanja>'):

                #uvjeti
                log_ili_izraz(cvor.djeca[0])
                if cvor.djeca[0].l_izraz[0] != 1:
                        _greska(cvor)
                izraz_pridruzivanja(cvor.djeca[2])
                if not _provjeri_tildu(cvor.djeca[2].tip[0], cvor.djeca[0].tip[0]):
                        _greska(cvor)

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.l_izraz.append(0)

        else:
                _greska(cvor)

def izraz(cvor):

        if cvor.djeca[0].ime == '<izraz_pridruzivanja>':

                #uvjeti
                izraz_pridruzivanja(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.l_izraz = cvor.djeca[0].l_izraz

        elif (cvor.djeca[0].ime == '<izraz>' and
              cvor.djeca[1].ime == 'ZAREZ' and
              cvor.djeca[2].ime == '<izraz_pridruzivanja>'):

                #uvjeti
                izraz(cvor.djeca[0])
                izraz_pridruzivanja(cvor.djeca[2])

                #dodjela
                cvor.tip = cvor.djeca[2].tip
                cvor.l_izraz.append(0)

        else:
                _greska(cvor)


#PRAVILA ZA NAREDBENU STRUKTURU PROGRAMA

def slozena_naredba(cvor):
        if (cvor.djeca[0].ime == 'L_VIT_ZAGRADA' and
                cvor.djeca[1].ime == '<lista_naredbi>' and
                cvor.djeca[2].ime == 'D_VIT_ZAGRADA'):

                #uvjeti
                lista_naredbi(cvor.djeca[1])

        elif (cvor.djeca[0].ime == 'L_VIT_ZAGRADA' and
                 cvor.djeca[1].ime == '<lista_deklaracija>' and
                 cvor.djeca[2].ime == '<lista_naredbi>' and
                 cvor.djeca[3].ime == 'D_VIT_ZAGRADA'):

                #uvjeti
                lista_deklaracija(cvor.djeca[1])
                lista_naredbi(cvor.djeca[2])

        else:
                _greska(cvor)


def lista_naredbi(cvor):
        if (cvor.djeca[0].ime == '<naredba>'):

                #uvjeti
                naredba(cvor.djeca[0])		#provjeri(<naredba>)

        elif (cvor.djeca[0].ime == '<lista_naredbi>' and
                 cvor.djeca[1].ime == '<naredba>'):

                #uvjeti
                lista_naredbi(cvor.djeca[0])	#provjeri(<lista_naredbi>)
                naredba(cvor.djeca[1])			#provjeri(<naredba>)

        else:
                _greska(cvor)


def naredba(cvor):
        if (cvor.djeca[0].ime == '<slozena_naredba>'):
                slozena_naredba(cvor.djeca[0])		#provjeri(<slozena_naredba>)

        elif (cvor.djeca[0].ime == '<izraz_naredba>'):
                izraz_naredba(cvor.djeca[0])		#provjeri(<izraz_naredba>)

        elif (cvor.djeca[0].ime == '<naredba_grananja>'):
                naredba_grananja(cvor.djeca[0])		#provjeri(<naredba_grananja>)

        elif (cvor.djeca[0].ime == '<naredba_petlje>'):
                naredba_petlje(cvor.djeca[0])		#provjeri(<naredba_petlje>)

        elif (cvor.djeca[0].ime == '<naredba_skoka>'):
                naredba_skoka(cvor.djeca[0])		#provjeri(<naredba_skoka>)

        else:
                _greska(cvor)

def izraz_naredba(cvor):
        if (cvor.djeca[0].ime == 'TOCKAZAREZ'):
                cvor.tip.append('int')		#tip  <- int

        elif (cvor.djeca[0].ime == '<izraz>' and
              cvor.djeca[1].ime == 'TOCKAZAREZ'):

                #uvjeti
                izraz(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip

        else:
                _greska(cvor)

def naredba_grananja(cvor):
        if (cvor.djeca[0].ime == 'KR_IF' and
            cvor.djeca[1].ime == 'L_ZAGRADA' and
            cvor.djeca[2].ime == '<izraz>' and
            cvor.djeca[3].ime == 'D_ZAGRADA' and
            cvor.djeca[4].ime == '<naredba>'):

                #uvjeti
                izraz(cvor.djeca[2])		#provjeri(<izraz>)
                if not _provjeri_tildu(cvor.djeca[2].tip[0], 'int'):
                        pass                    #izraz.tip ~ int
                naredba(cvor.djeca[4])          #provjeri(<naredba>)

        elif (cvor.djeca[0].ime == 'KR_IF' and
              cvor.djeca[1].ime == 'L_ZAGRADA' and
              cvor.djeca[2].ime == '<izraz>' and
              cvor.djeca[3].ime == 'D_ZAGRADA' and
              cvor.djeca[4].ime == '<naredba>' and
              cvor.djeca[5].ime == 'KR_ELSE' and
              cvor.djeca[6].ime == '<naredba>'):

                #uvjeti
                izraz(cvor.djeca[2])		#provjeri(<izraz>)
                if not _provjeri_tildu(cvor.djeca[2].tip[0], 'int'):
                        pass                    #<izraz>.tip ~ int
                naredba(cvor.djeca[4])          #provjeri(<naredba1>)
                naredba(cvor.djeca[6])          #provjeri(<naredba2>)

        else:
                _greska(cvor)

def naredba_petlje(cvor):
        if (cvor.djeca[0].ime == 'KR_WHILE' and
            cvor.djeca[1].ime == 'L_ZAGRADA' and
            cvor.djeca[2].ime == '<izraz>' and
            cvor.djeca[3].ime == 'D_ZAGRADA' and
            cvor.djeca[4].ime == '<naredba>'):

                #uvjeti
                izraz(cvor.djeca[2])		#provjeri(<izraz>)
                if not _provjeri_tildu(cvor.djeca[2].tip[0], 'int'):
                        pass                    #<izraz>.tip ~ int
                naredba(cvor.djeca[4])          #provjeri(<naredba>)

        elif (cvor.djeca[0].ime == 'KR_FOR' and
              cvor.djeca[1].ime == 'L_ZAGRADA' and
              cvor.djeca[2].ime == '<izraz_naredba>' and
              cvor.djeca[3].ime == '<izraz_naredba>' and
              cvor.djeca[4].ime == 'D_ZAGRADA' and
              cvor.djeca[5].ime == '<naredba>'):

                #uvjeti
                izraz_naredba(cvor.djeca[2])	#provjeri(<izraz_naredba1>)
                izraz_naredba(cvor.djeca[3])	#provjeri(<izraz_naredba2>)
                if not _provjeri_tildu(cvor.djeca[3].tip[0], 'int'):
                        pass                    #<izraz_naredba>2.tip ~ int
                naredba(cvor.djeca[5])			#provjeri(<naredba>)

        elif (cvor.djeca[0].ime == 'KR_FOR' and
              cvor.djeca[1].ime == 'L_ZAGRADA' and
              cvor.djeca[2].ime == '<izraz_naredba>' and
              cvor.djeca[3].ime == '<izraz_naredba>' and
              cvor.djeca[4].ime == '<izraz>' and
              cvor.djeca[5].ime == 'D_ZAGRADA' and
              cvor.djeca[6].ime == '<naredba>'):

                #uvjeti
                izraz_naredba(cvor.djeca[2])	#provjeri(<izraz_naredba1>)
                izraz_naredba(cvor.djeca[3])	#provjeri(<izraz_naredba2>)
                if not _provjeri_tildu(cvor.djeca[3].tip[0], 'int'):
                        pass                        #<izraz_naredba>2.tip ~ int
                izraz(cvor.djeca[4])			#provjeri(<izraz>)
                naredba(cvor.djeca[6])			#provjeri(<naredba>)

        else:
                _greska(cvor)

def naredba_skoka(cvor):
        global gen
        global poceo
        global x
        
        if ((cvor.djeca[0].ime == 'KR_CONTINUE' or
             cvor.djeca[0].ime == 'KR_BREAK') and
            cvor.djeca[1].ime == 'TOCKAZAREZ'):

                    #uvjeti
                    if not cvor.u_kontekstu('funkcija'):
                            _greska(cvor)

        elif (cvor.djeca[0].ime == 'KR_RETURN' and
              cvor.djeca[1].ime == 'TOCKAZAREZ'):

                ime_fun = cvor.unutar_funkcije()
                if ime_fun == 0:
                        _greska(cvor)
                definicija = cvor.pronadi_deklaraciju_funkcije(ime_fun)
                if definicija == 0 or len(definicija.pov) > 0:
                        _greska(cvor)

        elif (cvor.djeca[0].ime == 'KR_RETURN' and
              cvor.djeca[1].ime == '<izraz>' and
              cvor.djeca[2].ime == 'TOCKAZAREZ'):
                izraz(cvor.djeca[1])	#provjeri(<izraz>)

                ime_funkcije = cvor.unutar_funkcije()
                if ime_funkcije == 0:
                        _greska(cvor)
                definicija = cvor.pronadi_deklaraciju_funkcije(ime_funkcije)
                if definicija == 0 or definicija.pov == ['void']:
                        _greska(cvor)
                if not _provjeri_tildu (cvor.djeca[1].tip[0],
                                        definicija.pov[0]):
                        _greska(cvor)
            
                vrijednost = pronadi_lokalne (cvor.djeca[1])
                if (poceo == 0):
                    #gen += ""
                    gen += " LOAD R6, (G_X)\n"
                else:
                    gen += " MOVE %D " +  x + ", R6\n"
        else:
                _greska(cvor)


def pronadi_lokalne (cvor):
    for i in cvor.djeca:
            if i.ime == '<slozena_naredba>' or i.ime =='<vanjska_deklaracija>':
                # ovi cvorovi sadrze tablicu znakova
                for j in tablica_znakova:
                    print(j.tip, j.ime)
            elif i.ime == "<primarni_izraz>":
                return i.ljedinka
    return ""
       
def prijevodna_jedinica(cvor):
        if              (cvor.djeca[0].ime == '<vanjska_deklaracija>'):
                vanjska_deklaracija(cvor.djeca[0])		#provjeri(<vanjska_deklaracija>)

        elif    (cvor.djeca[0].ime == '<prijevodna_jedinica>' and
                        cvor.djeca[1].ime == '<vanjska_deklaracija>'):
                prijevodna_jedinica(cvor.djeca[0])		#provjeri(<prijevodna_jedinica>)
                vanjska_deklaracija(cvor.djeca[1])		#provjeri(<vanjska_deklaracija>)

        else:
                _greska(cvor)

def vanjska_deklaracija(cvor):
        if (cvor.djeca[0].ime == '<definicija_funkcije>'):
                definicija_funkcije(cvor.djeca[0])

        elif (cvor.djeca[0].ime == '<deklaracija>'):
                deklaracija(cvor.djeca[0])

        else:
                _greska(cvor)


#PRAVILA ZA DEKLARACIJE I DEFINICIJE

def definicija_funkcije (cvor):
        global gen
        if (cvor.djeca[0].ime == '<ime_tipa>' and
            cvor.djeca[1].ime == 'IDN' and
            cvor.djeca[2].ime == 'L_ZAGRADA' and
            cvor.djeca[3].ime == 'KR_VOID' and
            cvor.djeca[4].ime == 'D_ZAGRADA' and
            cvor.djeca[5].ime == '<slozena_naredba>'):

                cvor.ime_funkcije = cvor.djeca[1].ljedinka
                #uvjeti
                ime_tipa(cvor.djeca[0])
                if len(cvor.djeca[0].const) > 0 and cvor.djeca[0].const[0] == 1:
                        _greska(cvor)
                deklaracija = cvor.pronadi_deklaraciju_funkcije(
                        cvor.djeca[1].ljedinka)
                if deklaracija != 0 and deklaracija.je_def:
                        _greska(cvor)
                if deklaracija != 0: # postoji deklaracija
                        deklaracija.pov = cvor.djeca[0].tip
                else:
                        # deklaracija i definicija su jedno te ista stvar, sto
                        # se tablice znakova tice
                        cvor.dodaj_deklaraciju_funkcije(
                                Identifikator(cvor.ime_funkcije,
                                              tip=['funkcija'],
                                              je_def=1,
                                              params=['void'],
                                              pov = cvor.djeca[0].tip))
                if (cvor.ime_funkcije == "main"): 
                    gen += "F_MAIN" + " "
                else:
                    gen += "F_" + cvor.ime_funkcije + " "
                slozena_naredba(cvor.djeca[5])
                gen += "    RET\n"

        elif (cvor.djeca[0].ime == '<ime_tipa>' and
              cvor.djeca[1].ime == 'IDN' and
              cvor.djeca[2].ime == 'L_ZAGRADA' and
              cvor.djeca[3].ime == '<lista_parametara>' and
              cvor.djeca[4].ime == 'D_ZAGRADA' and
              cvor.djeca[5].ime == '<slozena_naredba>'):

                cvor.ime_funkcije = cvor.djeca[1].ime
                #uvjeti
                ime_tipa(cvor.djeca[0])
                if len(cvor.djeca[0].const) > 0:
                        _greska(cvor)
                deklaracija = cvor.pronadi_deklaraciju_funkcije(
                        cvor.djeca[1].ljedinka)
                if deklaracija != 0 and deklaracija.je_def:
                        _greska(cvor)
                if deklaracija != 0: # postoji deklaracija
                        deklaracija.pov = cvor.djeca[0].tip
                        deklaracija.je_def = 1
                cvor.dodaj_deklaraciju_funkcije(
                        Identifikator(cvor.ime_funkcije,
                                      tip=['funkcija'],
                                      je_def=1,
                                      params=cvor.djeca[3].tip,
                                      pov=cvor.djeca[0].tip))

                if (cvor.ime_funkcije == "main"): 
                    gen += "F_MAIN" + " "
                else:
                    gen += "F_" + cvor.ime_funkcije + " "
                slozena_naredba(cvor.djeca[5])
                gen += "    RET\n"

def lista_parametara (cvor):

        if (cvor.djeca[0].ime == '<deklaracija_parametra>'):

                #uvjeti
                deklaracija_parametra = cvor.djeca[0]

                #dodjela
                cvor.tip.extend(cvor.djeca[0].tip)
                cvor.imena.extend(cvor.djeca[0].imena)

        elif (cvor.djeca[0].ime == '<lista_parametara>' and
              cvor.djeca[1].ime == 'ZAREZ' and
              cvor.djeca[2].ime == '<deklaracija_parametra>'):

                #uvjeti
                lista_parametara(cvor.djeca[0])
                deklaracija_parametra(cvor.djeca[2])
                if cvor.djeca[2].imena[0] in cvor.djeca[0].imena:
                        _greska(cvor)

                #dodjela
                cvor.tip.extend(cvor.djeca[0].tip)
                cvor.tip.append(cvor.djeca[2].tip)
                cvor.imena.extend(cvor.djeca[0].tip)
                cvor.imena.append(cvor.djeca[2].tip)

        else:
                _greska(cvor)

def deklaracija_parametra (cvor):

        if (cvor.djeca[0].ime == '<ime_tipa>' and
            cvor.djeca[1].ime == 'IDN'):

                #uvjeti
                ime_tipa(cvor.djeca[0])
                if cvor.djeca[0].tip[0] == 'void':
                        _greska(cvor)

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.imena = cvor.djeca[1].ljedinka

        elif (cvor.djeca[0].ime == '<ime_tipa>' and
              cvor.djeca[1].ime == 'IDN' and
              cvor.djeca[2].ime == 'L_UGL_ZAGRADA' and
              cvor.djeca[3].ime == 'D_UGL_ZAGRADA'):

                #uvjeti
                ime_tipa(cvor.djeca[0])
                if cvor.djeca[0].tip[0] == 'void':
                        _greska(cvor)

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.niz.append[1]
                cvor.imena = cvor.djeca[1].ljedinka

        else:
                _greska(cvor)

def lista_deklaracija (cvor):
        if (cvor.djeca[0].ime == '<deklaracija>'):

                deklaracija(cvor.djeca[0])

        elif (cvor.djeca[0].ime == '<lista_deklaracija>' and
              cvor.djeca[1].ime == '<deklaracija>'):

                lista_deklaracija(cvor.djeca[0])
                deklaracija(cvor.djeca[1])

def deklaracija (cvor):
        if (cvor.djeca[0].ime == '<ime_tipa>' and
            cvor.djeca[1].ime == '<lista_init_deklaratora>' and
            cvor.djeca[2].ime == 'TOCKAZAREZ'):

                #uvjet 1
                ime_tipa(cvor.djeca[0])

                #dodjela nasljednog svojstva
                cvor.djeca[1].ntip = cvor.djeca[0].tip

                #uvjet 2
                lista_init_deklaratora(cvor.djeca[1])

        else:
                _greska(cvor)


def lista_init_deklaratora (cvor):
        if (cvor.djeca[0].ime == '<init_deklarator>'):

                #dodjela
                cvor.djeca[0].ntip = cvor.ntip

                #uvjeti
                init_deklarator(cvor.djeca[0])
        elif (cvor.djeca[0].ime == '<lista_init_deklaratora>' and
              cvor.djeca[1].ime == 'ZAREZ' and
              cvor.djeca[2].ime == '<init_deklarator>'):

                cvor.djeca[0].ntip = cvor.ntip				#<lista_init_deklaratora>2.ntip <-  <lista_init_deklaratora>1.ntip
                lista_init_deklaratora(cvor.djeca[0])		#provjeri(<lista_init_deklaratora>2)

                cvor.djeca[2].ntip = cvor.ntip				#<init_deklarator>.ntip <- <lista_init_deklaratora>1.ntip
                init_deklarator(cvor.djeca[2])				#provjeri(<init_deklarator>)

        else:
                _greska(cvor)


        ## ima jos

def init_deklarator (cvor):
        # bez len nikada ne preskace prvi uvjet
        if (cvor.djeca[0].ime == '<izravni_deklarator>' and
            len(cvor.djeca) == 1):

                #dodjela
                cvor.djeca[0].ntip = cvor.ntip

                #uvjeti
                izravni_deklarator(cvor.djeca[0])
                if len(cvor.djeca[0].const) > 0: #provjerava oba uvjeta
                        _greska(cvor)

        elif (cvor.djeca[0].ime == '<izravni_deklarator>' and
              cvor.djeca[1].ime == 'OP_PRIDRUZI' and
              cvor.djeca[2].ime == '<inicijalizator>'):
                cvor.djeca[0].ntip = cvor.ntip
                izravni_deklarator(cvor.djeca[0])
                inicijalizator(cvor.djeca[2])


                if (cvor.djeca[0].tip[0] in ['char', 'int'] or (len(cvor.djeca[0].const) > 0 and cvor.djeca[0].const[0] == 1)):	#ako je <izravni_deklarator>.tip T ili const(T)
                        if not _provjeri_tildu(cvor.djeca[2].tip[0], cvor.djeca[0].tip[0]):	#<inicijalizator>.tip ~ T
                                _greska(cvor)
                elif( len(cvor.djeca[0].niz) > 0 and cvor.djeca[0].niz[0] == 1 or
                      ( len(cvor.djeca[0].const) > 0 and cvor.djeca[0].const[0] == 1) and
                      cvor.djeca[0].niz[0] == 1):	#inace ako je <izravni_deklarator>.tip niz (T) ili niz (const(T))
                        if(cvor.djeca[2].br_elem > cvor.djeca[0].br_elem):	#<inicijalizator>.br-elem <= <izravni_deklarator>.br-elem
                                for i in cvor.djeca[2].tip:	#za svaki U iz <inicijalizator>.tipovi vrijedi U ~ T
                                        if not ( _provjeri_tildu(i, cvor.djeca[0].tip[0]) and _provjeri_tildu(i, cvor.djeca[0].tip[0]) ):
                                                _greska(cvor)
                        else:
                                _greska(cvor)
                else:
                        _greska(cvor)

        else:
                        _greska(cvor)


def izravni_deklarator (cvor):
        if cvor.djeca[0].ime == 'IDN':

                if cvor.ntip[0] == 'void':	#ntip != void
                        _greska(cvor)

                if (cvor.pronadi_deklaraciju(idn=cvor.djeca[0].ime, lokalno=1)):	#IDN.ime nije deklarirano u lokalnom djelokrugu
                        _greska(cvor)

                cvor.tip = cvor.ntip		#tip  <- ntip

                        #zabiljezi deklaraciju IDN.ime s odgovarajucim tipom
                cvor.dodaj_deklaraciju_varijable(Identifikator(
                                cvor.djeca[0].ljedinka,
                                tip=cvor.ntip[0]))
        elif ( cvor.djeca[0].ime == 'IDN' and
               cvor.djeca[1].ime == 'L_UGL_ZAGRADA' and
               cvor.djeca[2].ime == 'BROJ' and
               cvor.djeca[3].ime == 'D_UGL_ZAGRADA'):

                if cvor.ntip[0] == 'void':	#ntip != void
                        _greska(cvor)
                if (cvor.pronadi_deklaraciju(idn=cvor.djeca[0].ime, lokalno=1)):	#IDN.ime nije deklarirano u lokalnom djelokrugu
                        _greska(cvor)
                if (cvor.djeca[2].ljedinka > 0 and cvor.djeca[2].ljedinka < 1025):	#BROJ.vrijednost je pozitivan broj (> 0) ne veci od 1024
                        _greska(cvor)

                cvor.tip = cvor.ntip		#tip  <- niz (ntip)
                cvor.niz.append(1)
                cvor.br_elem = int( cvor.djeca[2].ljedinka )	#br-elem  <- BROJ.vrijednost
                        #zabiljezi deklaraciju IDN.ime s odgovarajucim tipom
                cvor.dodaj_u_tablicu_znakova(Identifikator(
                                cvor.djeca[0].ljedinka,
                                tip=cvor.ntip[0]))

        elif ( cvor.djeca[0].ime == 'IDN' and
               cvor.djeca[1].ime == 'L_ZAGRADA' and
               cvor.djeca[2].ime == 'KR_VOID' and
               cvor.djeca[3].ime == 'D_ZAGRADA'):

                cvor.param = cvor.ntip
                tmp = cvor.pronadi_deklaraciju_funkcije(idn=cvor.djeca[0].ime)
                if (tmp):	#IDN.ime je deklarirano u globalnom djelokrugu
                        # tmp je unos u tablici znakova
                        if(not (tmp.pov[0] == 'void' and tmp.param == cvor.ntip)):
                                _greska(cvor)
                        else:
                                tmp = Identifikator( cvor.djeca[0].ljedinka, param = cvor.ntip, pov = ['void'], tip = ['funkcija'], je_def = 0)
                                cvor.dodaj_deklaraciju_funkcije(tmp)

                cvor.tip.append('funkcija')
                cvor.pov.append('void')


        elif ( cvor.djeca[0].ime == 'IDN' and
               cvor.djeca[1].ime == 'L_ZAGRADA' and
               cvor.djeca[2].ime == '<lista_parametara>' and
               cvor.djeca[3].ime == 'D_ZAGRADA'):

                cvor.param = cvor.ntip
                lista_parametara(cvor.djeca[2])	#provjeri(lista_parametara)

                tmp = cvor.pronadi_deklaraciju_funkcije(idn=cvor.djeca[0].ime)
                if (tmp):	#IDN.ime je deklarirano u globalnom djelokrugu
                        # tmp je unos u tablici znakova
                        if(not (tmp.pov[0] == cvor.djeca[2].tip and tmp.param == cvor.ntip)):
                                _greska(cvor)
                else:
                        tmp = Identifikator( cvor.djeca[0].ljedinka, pov = cvor.djeca[2].tip, param = cvor.ntip, tip = ['funkcija'], je_def = 0)
                        cvor.dodaj_deklaraciju_funkcije(tmp)
        else:
                _greska(cvor)

def inicijalizator (cvor):

        if (cvor.djeca[0].ime == '<izraz_pridruzivanja>'):

                #uvjeti
                izraz_pridruzivanja(cvor.djeca[0])

                #dodjela
                niz = cvor.razrjesuje_u('NIZ_ZNAKOVA')
                if niz != 0:
                        cvor.br_elem = len(niz.ljedinka) + 1
                else:
                        cvor.tip = cvor.djeca[0].tip

        elif (cvor.djeca[0].ime == 'L_VIT_ZAGRADA' and
              cvor.djeca[1].ime == '<lista_izraza_pridruzivanja>' and
              cvor.djeca[2].ime == 'D_VIT_ZAGRADA'):

                #uvjeti
                lista_izraza_pridruzivanja(cvor.djeca[1])

                #dodjela
                cvor.br_elem = cvor.djeca[0].br_elem
                cvor.tip = cvor.djeca[0].tip

        else:
                _greska(cvor)

def lista_izraza_pridruzivanja (cvor):

        if (cvor.djeca[0].ime == '<izraz_pridruzivanja>'):

                #uvjeti
                izraz_priduzivanja(cvor.djeca[0])

                #dodjela
                cvor.tip = cvor.djeca[0].tip
                cvor.br_elem.append(1)

        elif (cvor.djeca[0].ime == '<lista_izraza_pridruzivanja>' and
              cvor.djeca[1].ime == 'ZAREZ' and
              cvor.djeca[2].ime == '<izraz_pridruzivanja>'):

                #uvjeti
                lista_izraza_pridruzivanja(cvor.djeca[0])
                izraz_pridruzivanja(cvor.djeca[2])

                #dodjela
                cvor.tip = cvor.djeca[0].tip + cvor.djeca[2].tip
                cvor.br_elem = cvor.djeca[0] + 1

        else:
                _greska(cvor)





#POMOCNE FUNKCIJE

def _greska(cvor):
        print("%s ::=" % cvor.ime, sep='', end='')
        for n in cvor.djeca:
                if n.ime[0] == '<':
                        print(" %s" % n.ime, sep='', end='')
                else:
                        print(" %s(%s,%s)" % (n.ime, n.redak, n.ljedinka),
                              sep='', end='')
        print()
        sys.exit(1)

def _unutar_raspona(broj):
        if -2 ** 31 <= int(broj) <= 2 ** 31 - 1:
                return(1)
        return(0)

def _ispravan_znak(znak):
        spec_znakovi = set(['\t', '\n', '\0', '\'', '\"', '\\', '"'])
        # ord vraca ascii vrijednost znaka
        # znak[1] zato sto je ljedinka oblika 'a'
        znak = znak[1]
        if ((ord('A') <= ord(znak) <= ord('Z')) or
                (ord('a') <= ord(znak) <= ord('z')) or
                znak in spec_znakovi):
                return(1)
        return(0)

def _ispravan_broj(broj):
        if -1 < broj < 256:
                return(1)
        return(0)

def _vrati_tip_l_izraz (cvor, ime_identifikatora):
        #trazi cvor u kojem je identifikator deklariran i uzima njegov tip i l-izraz
        cvor_deklaracije = cvor.pronadi_deklaraciju(idn=ime_identifikatora, lokalno=0)	#cvor_deklaracije je Identifikator
        if cvor_deklaracije == 0:	#ako identifikator nije deklariran
                return 0

        return [cvor_deklaracije.tip, cvor_deklaracije.l_izraz]		#vraca  tip i l-izraz

def _izravnaj (lista):

        nova_lista = []

        for n in lista:
                if hasattr(lista, "__iter__") and not isinstance(lista, basestring):
                        nova_lista.extend(_izravnaj(lista))
                else:
                        nova_lista.append(lista)

        return(nova_lista)

def _provjeri_tildu(tip1, tip2):
        if (not ( isinstance(tip1, str) and isinstance(tip2, str))):
                print ('Greska u provjeri_tildu, nisu predani stringovi')
        #ako su tipovi isti, nije potrebna provjera
        if (tip1 == tip2):
                return 1
        #Sve vrijednosti tipa const(T) mogu se implicitno pretvoriti u vrijednost tipa T
        elif ('niz' not in tip1 and 'const' in tip1):	#ako je tip1 oblika const(T)
                if (tip2 == tip1[6:-1]):				#ako je tip2 = T
                        return 1
                else:
                        return 0

        #sve vrijednosti tipa int ili char mogu se implicitno pretvoriti u vrijednosti
        #odgovarajuceg const-kvaliciranog tipa
        #Nadalje, sve vrijednosti tipa char mogu se implicitno pretvoriti u vrijednost tipa int
        elif ((tip1 == 'char' and tip2 == 'int') or
                        (tip1 == 'int' and tip2 == 'const(int)') or
                        (tip1 == 'char' and tip2 == 'const(char)')):
                return 1

        #vrijednost tipa niz (T) gdje T nije const-kvaliciran tip moze se pretvoriti
        #u vrijednost tipa niz (const(T))
        elif ('niz' in tip1 and 'const' not in tip1):				#ako je tip1 oblika niz(T)
                if ('const' not in tip1[4:-1]):						#ako T nije const-kvaliciran tip
                        if (('niz' not in tip2 and 'const' in tip2) and         #ako je tip2 oblika const(T)
                                (tip1[4:-1] == tip2[6:-1])):					#ako je T isti u niz(T) i const(T)
                                return 1

        else:
                return 0


stablo = SintaksnoStablo()
stog = []
preth_poz = 0
korijen = 1
gen = '';
vrj = []
dekl = ''

def main():
    global preth_poz
    global korijen
    global gen
    global vrj
    global poceo
    global x
    global dekl

    gen += "    MOVE 40000, r7\n"
    gen += "    CALL F_MAIN\n"
    gen += "    HALT\n"

    for line in sys.stdin:

        if korijen:
            stog.append(stablo.dodaj_korijen()) # pocetni nezavrsni znak
            korijen = 0
            continue

        poz = 0
        while line[poz] == ' ':  # odredi dubinu cvora po broju razmaka u prefiksu
            poz += 1

        line = line.strip()
        tmp = line.split() # ['<ime>', '<broj_retka>', '<l-izraz>'] ili ['<ime>']

        if poz <= preth_poz:                     # grana stabla je 'dovrsena'
            for n in range(preth_poz - poz + 1): # makni visak sa stoga
                stog.pop()

        if line[0] == '<': # nezavrsni znak
            stog.append(stog[-1].dodaj_cvor(tmp[0]))
        else:
            stog.append(stog[-1].dodaj_cvor(tmp[0], tmp[1], tmp[2]))
        preth_poz = poz

    prijevodna_jedinica(stablo.cvorovi[0])

#    nakon_obilaska()
    
#    gen += "    RET"
    datoteka = open('a.frisc','w', encoding='utf8')

    import pprint
#    pprint.pprint(gen)
#    pprint.pprint(stablo.cvorovi[0].tablica_znakova[0].tip)


    gen += dekl
    datoteka.write(gen)
    datoteka.close()
        
    sys.exit(0)


def nakon_obilaska ():
    global gen
    import pprint

    for n in stablo.cvorovi[0].tablica_znakova:
        if (type( n ) != Identifikator):
            #print("LEKS JEDINKA: " + n.ljedinka + "\n")

            if (n.top[0] == 'funkcija'):
                gen += "F_" + n.ime
            
#        print("IME: " + n.ime)
#        print("TIP: " + n.tip[0])

if __name__ == "__main__":
    main()
